package com.tuzhi.base.web.util;

import com.tuzhi.util.CharsetKit;
import com.tuzhi.util.ListTzUtil;
import com.tuzhi.util.MapTzUtil;
import com.tuzhi.util.StringTzUtil;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 */
public class RestTemplateUtil {

    /**
     * get方式下载文件
     * @param url
     * @return
     * @throws IOException
     */
    public static byte[] getDownloadFile(String url) throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        URI uri = URI.create(url);
        ResponseEntity<byte[]> response = restTemplate.getForEntity(uri, byte[].class);
        byte[] byts = response.getBody();
        return byts;
    }

    /**
     * post下载文件
     * @param url
     * @param headerMap
     * @param bodyObj
     * @return
     * @throws IOException
     */
    public static byte[] postDownloadFile(String url, Map<String, String> headerMap, Object bodyObj) throws Exception {
        RestTemplate restTemplate = new RestTemplate();
        URI uri = URI.create(url);
        HttpHeaders httpHeaders = buildHttpHeaders(headerMap);
        HttpEntity<Object> entity = new HttpEntity(bodyObj, httpHeaders);

        ResponseEntity<byte[]> response = restTemplate.postForEntity(uri, entity, byte[].class);
        byte[] byts = response.getBody();
        return byts;
    }

    /**
     * post传单个文件
     * @param url
     * @param fileName
     * @param file
     * @param paramMap
     * @return
     * @throws Exception
     */
    public static String postFile(String url, String fileName, File file, Map paramMap) throws Exception {
        return postFile(url, CharsetKit.UTF_8, null, fileName, file, paramMap);
    }

    /**
     * post传单个文件
     * @param url
     * @param charSet
     * @param headerMap
     * @param fileName
     * @param file
     * @param paramMap
     * @return
     * @throws Exception
     */
    public static String postFile(String url, String charSet, Map<String, String> headerMap,
                           String fileName, File file, Map paramMap) throws Exception {
        List<Map<String, File>> list = new ArrayList<>();
        Map<String, File> map = new HashMap<>();
        map.put(fileName, file);
        list.add(map);
        return postFiles(url, charSet, headerMap, list, paramMap);
    }

    public static String postFiles(String url, List<Map<String, File>> fileList, Map paramMap) throws Exception {
        return postFiles(url, null, null, fileList, paramMap);
    }

    /**
     * post传多个文件
     * @param url
     * @param charSet
     * @param headerMap
     * @param fileList
     * @param paramMap
     * @return
     * @throws Exception
     */
    public static String postFiles(String url, String charSet, Map<String, String> headerMap,
                           List<Map<String, File>> fileList, Map paramMap) throws Exception {

        if (ListTzUtil.isEmpty(fileList)) {
            throw new RuntimeException("文件List为空！");
        }

        charSet = StringTzUtil.isBlankNull(charSet)? "UTF-8" : charSet;
        try {

            //封装请求头
            HttpHeaders httpHeaders = buildHttpHeaders(headerMap);
            httpHeaders.set("Content-Type", MediaType.MULTIPART_FORM_DATA_VALUE + ";charset=" + charSet);

            //表单处理
            MultiValueMap<String, Object> form = buildMultiValueMap(paramMap);
            for (Map<String, File> map : fileList) {
                for (String key: map.keySet()) {
                    //文件处理
                    form.add(key, new FileSystemResource(map.get(key)));
                }
            }

            HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity(form, httpHeaders);
            RestTemplate restTemplate = new RestTemplate();
            //发送请求
            String rsp = restTemplate.postForObject(url, files, String.class);
            return rsp;
        } catch(Exception e){
            throw e;
        }
    }

    /**
     * post表单提交
     * @param url
     * @param headerMap
     * @param formMap
     * @return
     * @throws Exception
     */
    public static String postForm(String url, Map<String, String> headerMap, Map<String, ?> formMap) throws Exception {
        //封装请求头
        HttpHeaders httpHeaders = buildHttpHeaders(headerMap);
        //表单处理
        MultiValueMap<String, Object> form = buildMultiValueMap(formMap);
        HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity(form, httpHeaders);
        RestTemplate restTemplate = new RestTemplate();
        //发送请求
        String rsp = restTemplate.postForObject(url, httpEntity, String.class);
        return rsp;
    }

    public static String postBody(String url, Map<String, String> headerMap, Object obj) throws Exception {
        //封装请求头
        HttpHeaders httpHeaders = buildHttpHeaders(headerMap);
        //表单处理
        HttpEntity<Object> httpEntity = new HttpEntity(obj, httpHeaders);
        RestTemplate restTemplate = new RestTemplate();
        //发送请求
        String rsp = restTemplate.postForObject(url, httpEntity, String.class);
        return rsp;
    }

    public static ResponseEntity exchange(String url, String httpMethod, Map<String, String> headerMap,
                                          Object obj, Map<String, ?> paramMap) throws Exception {
        //封装请求头
        HttpHeaders httpHeaders = buildHttpHeaders(headerMap);
        //表单处理
        HttpEntity<Object> httpEntity = new HttpEntity(obj, httpHeaders);
        RestTemplate restTemplate = new RestTemplate();
        if (paramMap == null) {
            paramMap = new HashMap<>();
        }
        //发送请求
        ResponseEntity<String> rsp = restTemplate.exchange(url, HttpMethod.valueOf(httpMethod.toUpperCase()),
                httpEntity, String.class, paramMap);
        return rsp;
    }


    public static HttpHeaders buildHttpHeaders(Map<String, String> headerMap) {
        HttpHeaders httpHeaders = new HttpHeaders();
        if (MapTzUtil.isNotEmpty(headerMap)) {
            for (String key : headerMap.keySet()) {
                httpHeaders.set(key, headerMap.get(key));
            }
        }
        return httpHeaders;
    }

    public static MultiValueMap<String, Object> buildMultiValueMap(Map paramMap) {
        //表单处理
        MultiValueMap<String, Object> form = new LinkedMultiValueMap();
        if (MapTzUtil.isNotEmpty(paramMap)) {
            for (Object key: paramMap.keySet()) {
                //文件处理
                form.add(key + "", paramMap.get(key));
            }
        }
        return form;
    }

}
